package gui.diseaseEditor;

import gui.WuselPanelInterface;
import importExport.DiseaseImportExport;
import importExport.log.WuselLogger;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Properties;

import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import language.LanguageProfiler;
import dataTypes.Disease;
import javax.swing.ListSelectionModel;

/**
 * @author Kevin Wagner
 * @version 1.0
 * 
 */
public class DiseaseEditorPanel extends JPanel implements ActionListener,
		WuselPanelInterface {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2280504893624721185L;
	private JLabel diseaseL, nameL, illL, incubL, immuneL, infectionL,
			mortalityL, distanceL;
	private JTextField nameTxt, incubTxt, illTxt, immuneTxt, infectionTxt,
			mortTxt, distTxt;
	private JButton saveBtn, backBtn, newBtn, deleteBtn;
	private DefaultListModel lm = new DefaultListModel();
	final JList list = new JList(lm);

	private LanguageProfiler lp;
	private Properties props;

	private ArrayList<Disease> diseases;
	private Disease selectedDisease;

	/**
	 * @param props
	 * @param lp
	 */
	public DiseaseEditorPanel(Properties props, LanguageProfiler lp) {
		this.lp = lp;
		this.props = props;
		diseaseL = new JLabel();

		nameL = new JLabel();

		illL = new JLabel();

		incubL = new JLabel();

		JSeparator separator = new JSeparator();
		separator.setOrientation(SwingConstants.VERTICAL);

		immuneL = new JLabel();

		infectionL = new JLabel();

		mortalityL = new JLabel();

		distanceL = new JLabel();

		nameTxt = new JTextField();
		nameTxt.setColumns(10);

		incubTxt = new JTextField();
		incubTxt.setColumns(10);

		illTxt = new JTextField();
		illTxt.setColumns(10);

		immuneTxt = new JTextField();
		immuneTxt.setColumns(10);

		infectionTxt = new JTextField();
		infectionTxt.setColumns(10);

		mortTxt = new JTextField();
		mortTxt.setColumns(10);

		distTxt = new JTextField();
		distTxt.setColumns(10);

		saveBtn = new JButton();
		saveBtn.addActionListener(this);

		backBtn = new JButton();
		backBtn.addActionListener(this);

		JLabel lblH = new JLabel("h");
		lblH.setHorizontalTextPosition(SwingConstants.LEFT);
		lblH.setAlignmentX(Component.CENTER_ALIGNMENT);

		JLabel label = new JLabel("h");
		label.setHorizontalTextPosition(SwingConstants.LEFT);

		JLabel label_1 = new JLabel("h");
		label_1.setHorizontalTextPosition(SwingConstants.LEFT);

		newBtn = new JButton();
		newBtn.addActionListener(this);

		deleteBtn = new JButton();
		deleteBtn.addActionListener(this);
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		list.addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent e) {
				if (list.getSelectedIndex() > -1) {
					selectedDisease = diseases.get(list.getSelectedIndex());
					if (selectedDisease != null) {
						fillFields(selectedDisease);
					}
				}
			}
		});

		GroupLayout gl_contentPane = new GroupLayout(this);
		gl_contentPane
				.setHorizontalGroup(gl_contentPane
						.createParallelGroup(Alignment.LEADING)
						.addGroup(
								gl_contentPane
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.LEADING)
														.addComponent(
																list,
																GroupLayout.PREFERRED_SIZE,
																200,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(
																diseaseL,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(
																deleteBtn,
																Alignment.TRAILING,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.DEFAULT_SIZE,
																Short.MAX_VALUE)
														.addComponent(
																newBtn,
																Alignment.TRAILING,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.DEFAULT_SIZE,
																Short.MAX_VALUE))
										.addPreferredGap(
												ComponentPlacement.RELATED)
										.addComponent(separator,
												GroupLayout.PREFERRED_SIZE, 4,
												GroupLayout.PREFERRED_SIZE)
										.addGap(15)
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.TRAILING)
														.addGroup(
																gl_contentPane
																		.createSequentialGroup()
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.LEADING)
																						.addComponent(
																								incubL)
																						.addComponent(
																								nameL)
																						.addComponent(
																								illL)
																						.addComponent(
																								immuneL)
																						.addComponent(
																								infectionL)
																						.addComponent(
																								mortalityL)
																						.addComponent(
																								distanceL))
																		.addPreferredGap(
																				ComponentPlacement.UNRELATED)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.LEADING)
																						.addComponent(
																								distTxt,
																								GroupLayout.DEFAULT_SIZE,
																								616,
																								Short.MAX_VALUE)
																						.addComponent(
																								mortTxt,
																								GroupLayout.DEFAULT_SIZE,
																								616,
																								Short.MAX_VALUE)
																						.addComponent(
																								infectionTxt,
																								GroupLayout.DEFAULT_SIZE,
																								616,
																								Short.MAX_VALUE)
																						.addComponent(
																								nameTxt,
																								GroupLayout.DEFAULT_SIZE,
																								616,
																								Short.MAX_VALUE)
																						.addGroup(
																								gl_contentPane
																										.createSequentialGroup()
																										.addGroup(
																												gl_contentPane
																														.createParallelGroup(
																																Alignment.LEADING)
																														.addComponent(
																																immuneTxt,
																																GroupLayout.DEFAULT_SIZE,
																																354,
																																Short.MAX_VALUE)
																														.addComponent(
																																illTxt,
																																GroupLayout.DEFAULT_SIZE,
																																354,
																																Short.MAX_VALUE)
																														.addComponent(
																																incubTxt,
																																GroupLayout.DEFAULT_SIZE,
																																354,
																																Short.MAX_VALUE))
																										.addPreferredGap(
																												ComponentPlacement.RELATED)
																										.addGroup(
																												gl_contentPane
																														.createParallelGroup(
																																Alignment.TRAILING)
																														.addComponent(
																																label_1,
																																GroupLayout.DEFAULT_SIZE,
																																258,
																																Short.MAX_VALUE)
																														.addComponent(
																																label,
																																GroupLayout.DEFAULT_SIZE,
																																258,
																																Short.MAX_VALUE)
																														.addComponent(
																																lblH,
																																Alignment.LEADING,
																																GroupLayout.DEFAULT_SIZE,
																																258,
																																Short.MAX_VALUE)))))
														.addGroup(
																gl_contentPane
																		.createSequentialGroup()
																		.addComponent(
																				saveBtn,
																				GroupLayout.DEFAULT_SIZE,
																				337,
																				Short.MAX_VALUE)
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addComponent(
																				backBtn,
																				GroupLayout.DEFAULT_SIZE,
																				338,
																				Short.MAX_VALUE)))
										.addContainerGap()));
		gl_contentPane
				.setVerticalGroup(gl_contentPane
						.createParallelGroup(Alignment.TRAILING)
						.addGroup(
								gl_contentPane
										.createSequentialGroup()
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.LEADING)
														.addGroup(
																gl_contentPane
																		.createSequentialGroup()
																		.addComponent(
																				diseaseL)
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addComponent(
																				list,
																				GroupLayout.DEFAULT_SIZE,
																				562,
																				Short.MAX_VALUE)
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addComponent(
																				newBtn)
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addComponent(
																				deleteBtn))
														.addGroup(
																gl_contentPane
																		.createSequentialGroup()
																		.addContainerGap()
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								nameL)
																						.addComponent(
																								nameTxt,
																								GroupLayout.PREFERRED_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.PREFERRED_SIZE))
																		.addGap(18)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								incubL)
																						.addComponent(
																								incubTxt,
																								GroupLayout.PREFERRED_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.PREFERRED_SIZE)
																						.addComponent(
																								lblH))
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								illL)
																						.addComponent(
																								illTxt,
																								GroupLayout.PREFERRED_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.PREFERRED_SIZE)
																						.addComponent(
																								label))
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								immuneL)
																						.addComponent(
																								immuneTxt,
																								GroupLayout.PREFERRED_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.PREFERRED_SIZE)
																						.addComponent(
																								label_1))
																		.addGap(18)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								infectionL)
																						.addComponent(
																								infectionTxt,
																								GroupLayout.PREFERRED_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.PREFERRED_SIZE))
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								mortalityL)
																						.addComponent(
																								mortTxt,
																								GroupLayout.PREFERRED_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.PREFERRED_SIZE))
																		.addGap(18)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								distanceL)
																						.addComponent(
																								distTxt,
																								GroupLayout.PREFERRED_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.PREFERRED_SIZE))
																		.addGap(18)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.BASELINE)
																						.addComponent(
																								backBtn)
																						.addComponent(
																								saveBtn)))
														.addComponent(
																separator,
																GroupLayout.DEFAULT_SIZE,
																640,
																Short.MAX_VALUE))
										.addContainerGap()));
		this.setLayout(gl_contentPane);
		updateLanguage();
		loadData();
	}

	private void fillFields(Disease d) {
		nameTxt.setText(d.getName());
		incubTxt.setText(d.getIncubationTime() + "");
		illTxt.setText(d.getIllTime() + "");
		immuneTxt.setText(d.getImmuneTime() + "");
		infectionTxt.setText(d.getInfectionProbability() + "");
		mortTxt.setText(d.getMortalityProbability() + "");
		distTxt.setText(d.getInfectionDistance() + "");
	}

	public boolean checkForChanges() {
		boolean temp = false;
		try {
			temp = temp
					|| (!selectedDisease.getName().equals(nameTxt.getText()));
			temp = temp
					|| (selectedDisease.getIncubationTime() != Integer
							.parseInt(incubTxt.getText()));
			temp = temp
					|| (selectedDisease.getIllTime() != Integer.parseInt(illTxt
							.getText()));
			temp = temp
					|| (selectedDisease.getImmuneTime() != Integer
							.parseInt(immuneTxt.getText()));
			temp = temp
					|| (selectedDisease.getInfectionProbability() != Double
							.parseDouble(infectionTxt.getText()));
			temp = temp
					|| (selectedDisease.getMortalityProbability() != Double
							.parseDouble(mortTxt.getText()));
			temp = temp
					|| (selectedDisease.getInfectionDistance() != Short
							.parseShort(distTxt.getText()));
		} catch (Exception e) {
			return true;
		}
		return temp;
	}

	private void loadData() {
		diseases = DiseaseImportExport.importDisease(props);
		fillList();
		if (diseases.size() > 0) {
			selectedDisease = diseases.get(0);
			list.setSelectedIndex(0);
			fillFields(selectedDisease);
		}
	}

	private void fillList() {
		lm.removeAllElements();
		for (int i = 0; i < diseases.size(); i++) {
			lm.addElement(diseases.get(i).getName());
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == saveBtn) {
			saveData();
			fillList();

		} else if (e.getSource() == backBtn) {
			if (checkForChanges()) {
				confirmDialog();
			}
			fillFields(selectedDisease);

		} else if (e.getSource() == newBtn) {
			boolean status = true;
			if (checkForChanges()) {
				status = confirmDialog();
			}
			if (status) {
				Disease d = new Disease();
				d.setName("Name");
				d.setIncubationTime(1);
				d.setIllTime(1);
				d.setImmuneTime(1);
				d.setInfectionProbability(1.0);
				d.setMortalityProbability(0.0);
				d.setInfectionDistance((short) 100);
				diseases.add(d);
				fillList();
				selectedDisease = d;
				fillFields(selectedDisease);
			}

		} else if (e.getSource() == deleteBtn) {
			boolean status = true;
			if (diseases.get(list.getSelectedIndex()) != selectedDisease) {
				if (checkForChanges()) {
					status = status && confirmDialog();
				}
			}
			if (status) {
				if (DiseaseImportExport.deleteDiseaseFile(
						diseases.get(list.getSelectedIndex()), props)) {
					diseases.remove(list.getSelectedIndex());
					fillList();
					if (diseases.size() > 0) {
						list.setSelectedIndex(0);
						fillFields(diseases.get(0));
						selectedDisease = diseases.get(0);
					}
					JOptionPane.showMessageDialog(this,
							lp.getLocalizedString("entryDelete"),
							lp.getLocalizedString("entryDelete"),
							JOptionPane.INFORMATION_MESSAGE);
				} else {
					JOptionPane.showMessageDialog(this,
							lp.getLocalizedString("deleteError"),
							lp.getLocalizedString("deleteErrorTitle"),
							JOptionPane.ERROR_MESSAGE);
				}
			}
		}
	}

	@Override
	public boolean confirmDialog() {
		int result = JOptionPane.showConfirmDialog(this,
				lp.getLocalizedString("confirmChanges"),
				lp.getLocalizedString("confirmChangesTitle"),
				JOptionPane.YES_NO_OPTION);
		if (result == JOptionPane.YES_OPTION) {
			return saveData();
		}
		return true;
	}

	/**
	 * 
	 * @return status of saving
	 */
	public boolean saveData() {
		try {
			String name = nameTxt.getText();
			int incub = Integer.parseInt(incubTxt.getText());
			int ill = Integer.parseInt(illTxt.getText());
			int immune = Integer.parseInt(immuneTxt.getText());
			double infectionProb = Double.parseDouble(infectionTxt.getText());
			double mort = Double.parseDouble(mortTxt.getText());
			short dist = Short.parseShort(distTxt.getText());
			selectedDisease.setName(name);
			selectedDisease.setIncubationTime(incub);
			selectedDisease.setIllTime(ill);
			selectedDisease.setImmuneTime(immune);
			selectedDisease.setInfectionProbability(infectionProb);
			selectedDisease.setMortalityProbability(mort);
			selectedDisease.setInfectionDistance(dist);
			DiseaseImportExport.exportDisease(selectedDisease,
					new File(props.getProperty("diseaseDir", "Disease")));
		} catch (Exception e) {
			WuselLogger.log.error(e.getLocalizedMessage());
			JOptionPane.showMessageDialog(
					this,
					lp.getLocalizedString("saveError") + " \n"
							+ e.getLocalizedMessage(),
					lp.getLocalizedString("saveErrorTitle"),
					JOptionPane.ERROR_MESSAGE);
			return false;
		}
		return true;
	}

	@Override
	public void updateLanguage() {
		diseaseL.setText(lp.getLocalizedString("diseases"));
		nameL.setText(lp.getLocalizedString("name"));
		illL.setText(lp.getLocalizedString("ill"));
		incubL.setText(lp.getLocalizedString("incub"));
		immuneL.setText(lp.getLocalizedString("immune"));
		infectionL.setText(lp.getLocalizedString("infection"));
		mortalityL.setText(lp.getLocalizedString("mort"));
		distanceL.setText(lp.getLocalizedString("dist"));

		saveBtn.setText(lp.getLocalizedString("saveEntry"));
		backBtn.setText(lp.getLocalizedString("back"));
		deleteBtn.setText(lp.getLocalizedString("delete"));
		newBtn.setText(lp.getLocalizedString("new"));
	}

}
